// insert here for test
#include <deque>
#include <queue>
#include <stack>
// insert end
#include <iostream>
#include <algorithm>
#include <string>
#include <ctime>
#include <cstdlib>

#include <malloc.h>

#include "test.h"
#include "print.hpp" // for print


using std::cin;
using std::cout;
using std::endl;

using std::deque;
using std::queue;
using std::stack;

using std::string;

const long STRING_LENGTH = 10;

void test_deque(const long& value) {
    print("test_deque() ...");

    deque<string> c;

    print("start insert...");
    TimeCounter t;
    for (long i = 0; i<value; ++i) {
        c.push_back(get_a_random_string(STRING_LENGTH));
    }
    t.endAndShow("inset use time: ");
    print("deque.size() = ", c.size());
    print("deque.front() = ", c.front());
    print("deque.back() = ", c.back());
    print("deque.max_size() = ", c.max_size());

    print("string find...");
    string target = get_a_target_string();
    t.start();
    auto pItem = std::find(c.begin(), c.end(), target);
    t.endAndShow("find use time: ");

    if (pItem != c.end()) {
        print("found, ", *pItem);
    } else {
        print("sorry, not found");
    }

    print("start sort...");
    t.start();
    std::sort(c.begin(), c.end());
    t.endAndShow("sort use time: ");
}

void test_queue(const long& value) {
    print("test_queue...");
    queue<string> c;
    print("start insert...");
    TimeCounter t;
    for (long i = 0; i<value; ++i) {
        c.push(get_a_random_string(STRING_LENGTH));
    }
    t.endAndShow("insert use time(s): ");
    print("queue.size = ", c.size());
    print("queue.front = ", c.front());
    print("queue.back = ", c.back());
    print("pop now!");
    c.pop();
    print("queue.size = ", c.size());
    print("queue.front = ", c.front());
    print("queue.back = ", c.back());
}

void test_stack(const long& value) {
    print("test_stack...");
    stack<string> c;
    print("start insert...");
    TimeCounter t;
    for (long i = 0; i<value; ++i) {
        c.push(get_a_random_string(STRING_LENGTH));
    }
    t.endAndShow("insert use time(s): ");
    print("stack.size = ", c.size());
    print("stack.top = ", c.top());
    print("pop now!");
    print("stack.size = ", c.size());
    print("stack.top = ", c.top());
}

void menu() {
    cout << "Enter a number: " << endl
        << "1. test deque;" << endl
        << "2. test queue;" << endl
        << "3. test stack;" << endl
        << "q. end." << endl;
}

int main(void) {
    print("start...");
    const long value = get_a_target_long();

    char option;
    print("Please input a option");
    menu();
    while (cin >> option) {
        switch (option) {
            case '1':
                test_deque(value);
                print("end test deque");
                print("-----------");
                break;
            case '2':
                test_queue(value);
                print("end test queue");
                print("-----------");
                break;
            case '3':
                test_stack(value);
                print("end test stack");
                print("-----------");
                break;
            case 'q':
                print("buy!");
                return 0;
            default:
                print("wrong option");
                break;
        }
        // 确保下次执行有最优效率
        malloc_trim(0);
        menu();
    }


    return 0;
}



